package com.wt.struggle.goodbye.wxutil;

import android.app.Activity;
import android.content.Context;
import android.net.wifi.WifiInfo;
import android.net.wifi.WifiManager;
import android.os.AsyncTask;
import android.util.Log;
import android.util.Xml;
import android.widget.Toast;

import com.tencent.mm.opensdk.modelmsg.SendAuth;
import com.tencent.mm.opensdk.modelpay.PayReq;
import com.tencent.mm.opensdk.openapi.IWXAPI;
import com.tencent.mm.opensdk.openapi.WXAPIFactory;

import com.wt.struggle.goodbye.base.Config;
import com.xin.lv.yang.utils.info.HttpInfo;
import com.xin.lv.yang.utils.utils.HttpUtils;

import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.xml.sax.SAXException;
import org.xmlpull.v1.XmlPullParser;

import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.StringReader;
import java.io.UnsupportedEncodingException;
import java.lang.ref.WeakReference;

import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.Random;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;

/**
 * 微信支付操作
 */
public class WXPay {

    private IWXAPI api;

    public WXPay(Context context) {

        activity = (Activity) context;
        api = WXAPIFactory.createWXAPI(context, Contact.WEIXIN_ID, true);

        /// 将该app注册到微信
        boolean b = api.registerApp(Contact.WEIXIN_ID);

        Log.i("result", "bbbbbbb----------" + b);

        task = new WeiXinAsyncTask(this);

    }


    /**
     * 微信三方登录
     */
    public void weixinLogin() {
        SendAuth.Req req = new SendAuth.Req();
        req.scope = "snsapi_userinfo";
        req.state = activity.getPackageName();
        boolean b = api.sendReq(req);

        Log.i("result", "发送成功-------" + b);
    }


    private Activity activity;
    private WeiXinAsyncTask task;
    private float money;
    private String orderNum;
    private String title;

    public void tiOrder(float money, String orderNum, String title) {
        this.money = money;
        this.orderNum = orderNum;
        this.title = title;
        task.execute();
    }


    /**
     * 使用异步任务生成订单，成功后返回预付订单的id
     * 先生成订单成功后，才可以获取到预付的id
     */
    private static class WeiXinAsyncTask extends AsyncTask<String, Void, Map<String, String>> {
        /// 弱引用
        WeakReference<WXPay> weakReference;

        public WeiXinAsyncTask(WXPay wxPay) {
            weakReference = new WeakReference<>(wxPay);
        }

        WXPay wxPay;

        @Override
        protected Map<String, String> doInBackground(String... strings) {

            wxPay = weakReference.get();

            List<HttpInfo> list = wxPay.createList();

            String sign = wxPay.pingListAndSign(list);

            Log.i("result", "sign======" + sign);

            String order = wxPay.createXML(list, sign);

            Log.i("result", "order=====" + order);

            String url = String.format("https://api.mch.weixin.qq.com/pay/unifiedorder", Locale.CHINA);

            String str = HttpUtils.getInstance().postXML(url, order);

            Log.i("result", "返回数据map====" + str);

            Map<String, String> map = getMapFromXML(str);

            return map;

        }


        @Override
        protected void onPostExecute(Map<String, String> stringStringMap) {
            super.onPostExecute(stringStringMap);
            if (stringStringMap != null) {
                wxPay.pay(stringStringMap);
            }

        }

    }


    private void pay(Map<String, String> map) {

        String code1 = map.get("return_code");
        String code2 = map.get("result_code");

        if (code1.equals("SUCCESS") && code2.equals("SUCCESS")) {
            PayReq request = new PayReq();
            request.appId = Contact.WEIXIN_ID;
            request.partnerId = Contact.MCH_ID;
            request.prepayId = map.get("prepay_id");
            request.packageValue = "Sign=WXPay";
            request.nonceStr = nonceStr;
            request.timeStamp = String.valueOf(System.currentTimeMillis());

            List<HttpInfo> list = new ArrayList<>();
            list.add(new HttpInfo("appid", Contact.WEIXIN_ID));
            list.add(new HttpInfo("noncestr", nonceStr));
            list.add(new HttpInfo("package", "Sign=WXPay"));
            list.add(new HttpInfo("partnerid", Contact.MCH_ID));
            list.add(new HttpInfo("prepayid", request.prepayId));
            list.add(new HttpInfo("timestamp", request.timeStamp));

            String sign = pingListAndSign(list);

            Log.i("wwwwww", "再次签名信息=====" + sign);

            request.sign = sign;

            api.sendReq(request);

        } else {

            Toast.makeText(activity, "微信支付失败", Toast.LENGTH_SHORT).show();

        }
    }


    /**
     * 获取ip地址
     *
     * @param activity
     * @return
     */
    public String getIp(Activity activity) {
        //获取wifi服务
        WifiManager wifiManager = (WifiManager) activity.getApplicationContext().getSystemService(Context.WIFI_SERVICE);
        //判断wifi是否开启
        if (!wifiManager.isWifiEnabled()) {
            wifiManager.setWifiEnabled(true);
        }
        WifiInfo wifiInfo = wifiManager.getConnectionInfo();
        int ipAddress = wifiInfo.getIpAddress();
        String ip = int2ip(ipAddress);
        return ip;
    }


    private static String int2ip(int ipInt) {
        StringBuilder sb = new StringBuilder();
        sb.append(ipInt & 0xFF).append(".");
        sb.append((ipInt >> 8) & 0xFF).append(".");
        sb.append((ipInt >> 16) & 0xFF).append(".");
        sb.append((ipInt >> 24) & 0xFF);
        return sb.toString();
    }


    private String nonceStr;   // 随机字符串

    /**
     * 微信回调地址
     */
    private static String notifyUrl = Config.IP + "/App/shop/weixcallback";

    /**
     * 创建数据集合 按字符顺序
     *
     * @return 数据集合
     */
    private List<HttpInfo> createList() {
        List<HttpInfo> list = new ArrayList<>();

        nonceStr = getNonceStr();
        nonceStr = nonceStr.toUpperCase();

        list.add(new HttpInfo("appid", Contact.WEIXIN_ID));
        list.add(new HttpInfo("attach", title));
        list.add(new HttpInfo("body", title));
        list.add(new HttpInfo("mch_id", Contact.MCH_ID));
        list.add(new HttpInfo("nonce_str", nonceStr));
        list.add(new HttpInfo("notify_url", notifyUrl));
        list.add(new HttpInfo("out_trade_no", orderNum));
        list.add(new HttpInfo("spbill_create_ip", getIp(activity)));
        list.add(new HttpInfo("total_fee", String.valueOf((int) (money * 100))));
        list.add(new HttpInfo("trade_type", "APP"));

        return list;

    }


    /**
     * 获取随机字符串
     *
     * @return 字符串
     */
    private String getNonceStr() {
        Random random = new Random();
        return MD5.getMessageDigest(String.valueOf(random.nextInt(10000)).getBytes());
    }


    /**
     * 生成订单号
     *
     * @return 订单号的字符串
     */
    private String getTimeStamp() {
        SimpleDateFormat format = new SimpleDateFormat("MMddHHmmss", Locale.getDefault());
        Date date = new Date();
        String key = format.format(date);
        Random r = new Random();
        key = key + r.nextInt();
        key = key.substring(0, 15);
        return key;
    }


    private String pingListAndSign(List<HttpInfo> list) {
        StringBuilder builder = new StringBuilder();
        int len = list.size();
        for (int i = 0; i < len; i++) {
            HttpInfo httpInfo = list.get(i);
            builder.append(httpInfo.getKey());
            builder.append("=");
            builder.append(httpInfo.getValues());
            builder.append("&");

        }

        builder.append("key=");
        builder.append(Contact.KEY);

        Log.i("wwwwww", "签名数据====" + builder.toString());

        byte[] str = new byte[0];
        try {
            str = builder.toString().getBytes("utf-8");
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        }

        return MD5.getMessageDigest(str).toUpperCase();

    }


    private String createXML(List<HttpInfo> list, String sign) {
        StringBuilder builder = new StringBuilder();
        builder.append("<xml>");
        for (HttpInfo t : list) {
            builder.append("<" + t.getKey() + ">");
            builder.append(t.getValues());
            builder.append("</" + t.getKey() + ">");

        }

        builder.append("<sign>");
        builder.append(sign);
        builder.append("</sign>");

        builder.append("</xml>");

        return builder.toString();

    }


    private Map<String, String> DecodeXml(String content) {
        Map<String, String> map = new HashMap<String, String>();
        try {
            XmlPullParser parser = Xml.newPullParser();
            parser.setInput(new StringReader(content));
            int event = parser.getEventType();
            while (event != XmlPullParser.END_DOCUMENT) {
                String nodeName = parser.getName();
                switch (event) {
                    case XmlPullParser.START_DOCUMENT:

                        break;
                    case XmlPullParser.START_TAG:

                        if (!nodeName.equals("xml")) {

                            map.put(nodeName, parser.nextText());
                        }
                        break;
                    case XmlPullParser.END_TAG:
                        break;
                }

                event = parser.next();
            }

        } catch (Exception e) {

        }

        return map;
    }


    /**
     * xml 转map集合
     *
     * @param xmlString xml数据
     * @return map集合数据
     */
    private static Map<String, String> getMapFromXML(String xmlString) {
        //  这里用Dom的方式解析回包的最主要目的是防止API新增回包字段
        DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
        try {
            DocumentBuilder builder = factory.newDocumentBuilder();
            InputStream is = new ByteArrayInputStream(xmlString.getBytes());
            Document document = builder.parse(is);

            NodeList allNodes = document.getFirstChild().getChildNodes();
            Node node;
            Map<String, String> map = new HashMap<String, String>();
            int i = 0;
            while (i < allNodes.getLength()) {
                node = allNodes.item(i);
                if (node instanceof Element) {
                    map.put(node.getNodeName(), node.getTextContent());
                }
                i++;
            }
            return map;

        } catch (ParserConfigurationException e) {
            e.printStackTrace();
        } catch (SAXException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }

        return null;

    }


    /**
     * 获取支付id 信息
     *
     * @param xml xml 数据
     * @return 获取的字符串
     */
    private String getPrepayId(String url, String xml) {
        byte[] buf = Util.httpPost(url, xml);
        if (buf != null) {
            String content = new String(buf);

            return content;
        }

        return null;

    }


}
